#include "changeuseravatardialog.h"
#include "changeuseravatartask.h"
#include "libs/controls/toastlabel.h"
#include "libs/core/user/localuser.h"
#include "libs/thirdparty/imageutils/imageutils.h"
#include "usersettings.h"
#include "utils/utils.h"
#include "yingce.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>

ChangeAvatarDialog::ChangeAvatarDialog(QWidget* parent)
    : QDialog { parent, Qt::MSWindowsFixedSizeDialogHint }
{
    setWindowTitle(tr("Change Avatar"));
    setMinimumSize(450, 520);
    resize(450, 520);

    QVBoxLayout* vl = new QVBoxLayout(this);
    vl->setContentsMargins(0, 0, 0, 20);
    vl->setSpacing(20);

    QLabel* avatar_label = new QLabel(this);
    avatar_label->setObjectName("avatar");
    avatar_label->setAlignment(Qt::AlignCenter);
    avatar_label->setScaledContents(true);
    vl->addWidget(avatar_label, 1);

    if (!YingCe::instance()->localUser()->avatar().isEmpty()) {
        const QString path = UserSettings::instance().resDir().absoluteFilePath(
                YingCe::instance()->localUser()->avatar());
        avatar_label->setPixmap(path);
    }

    QPushButton* change_button = new QPushButton(tr("Change"), this);
    change_button->setObjectName("change");
    vl->addWidget(change_button, 0, Qt::AlignHCenter);

    connect(change_button, &QPushButton::clicked, this, [this, avatar_label] {
        QString path = QFileDialog::getOpenFileName(
                this, tr("Select Avatar"), UserSettings::instance().accessDir().absolutePath(),
                tr("Images (*.png *.jpg *.jpeg)"));
        if (!path.isEmpty()) {
            QFileInfo fi(path);
            if (fi.size() > 2 * 1024 * 1024) {
                utils::msgBox(this, tr("Select Avatar"),
                              tr("The image file size is greater than 2MB, please select a file no "
                                 "larger than 2MB."));
                return;
            }
            if (fi.size() > 500 * 1024) {
                if (!imageutils::compressImage(path, UserSettings::instance().tempDir(), path)) {
                    yc::ToastLabel::showMessage(
                            tr("Failed to compress the image, pls choose another."), this);
                    return;
                }
            }
            QPixmap pixmap(path);
            if (pixmap.width() == 0) {
                yc::ToastLabel::showMessage(tr("Failed to load the image, pls choose another."),
                                            this);
                return;
            }

            QString avatar_path;
            if (pixmap.width() != pixmap.height()) {
                qreal ratio = qreal(pixmap.height()) / qreal(pixmap.width());
                int w, h, x, y;
                if (ratio > 1.0) {
                    w = pixmap.width();
                    h = w;
                    x = 0;
                    y = (pixmap.height() - h) / 2;
                } else {
                    h = pixmap.height();
                    w = h;
                    x = (pixmap.width() - w) / 2;
                    y = 0;
                }
                const QString new_path = UserSettings::instance().tempDir().absoluteFilePath(
                        "yingce-avatar-temp.png");
                QPixmap new_pixmap = pixmap.copy(QRect(x, y, w, h));
                if (!new_pixmap.save(new_path)) {
                    yc::ToastLabel::showMessage(tr("Failed to cut out the avatar."), this);
                    return;
                }
                if (!imageutils::compressImage(new_path, UserSettings::instance().tempDir(),
                                               avatar_path)) {
                    avatar_path = new_path;
                }
                pixmap = new_pixmap;
            } else {
                avatar_path = path;
            }
            avatar_label->setPixmap(
                    pixmap.scaled(QSize(256, 256), Qt::KeepAspectRatio, Qt::SmoothTransformation));
            ChangeUserAvatarTask* t = new ChangeUserAvatarTask(avatar_path, this);
            connect(t, &ChangeUserAvatarTask::finished, this,
                    [this] { yc::ToastLabel::showMessage(tr("Success."), this); });
            connect(t, &ChangeUserAvatarTask::failed, this, [this](int error, const QString& msg) {
                yc::ToastLabel::showMessage(msg, this);
            });
            t->start();
        }
    });
}
